#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
讯飞语音转写服务
基于讯飞开放平台 API 实现音频文件转写功能
"""

import os
import time
import hashlib
import base64
import json
import requests
from flask import Flask, request, jsonify
from flask_cors import CORS
from werkzeug.utils import secure_filename
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)

# 配置参数
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'wav', 'mp3', 'm4a', 'flac'}
MAX_FILE_SIZE = 50 * 1024 * 1024  # 50MB

# 讯飞开放平台配置 (需要替换为实际的APPID和API_KEY)
XFYUN_APPID = "your_appid_here"
XFYUN_API_KEY = "your_api_key_here"
XFYUN_API_SECRET = "your_api_secret_here"

# 创建上传目录
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE

def allowed_file(filename):
    """检查文件扩展名是否允许"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def get_audio_file_base64(file_path):
    """将音频文件转换为base64编码"""
    try:
        with open(file_path, 'rb') as f:
            audio_content = f.read()
        return base64.b64encode(audio_content).decode('utf-8')
    except Exception as e:
        logger.error(f"读取音频文件失败: {str(e)}")
        return None

def build_xfyun_request_header(api_key, api_secret):
    """构建讯飞API请求头"""
    try:
        # 生成时间戳
        cur_time = str(int(time.time()))
        
        # 生成随机字符串
        param = {"aue": "raw", "language": "zh_cn", "accent": "mandarin"}
        param_base64 = base64.b64encode(json.dumps(param).encode('utf-8')).decode('utf-8')
        
        # 生成签名
        check_sum = hashlib.md5((api_key + cur_time + param_base64).encode('utf-8')).hexdigest()
        
        header = {
            'X-CurTime': cur_time,
            'X-Param': param_base64,
            'X-Appid': XFYUN_APPID,
            'X-CheckSum': check_sum,
            'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
        }
        
        return header
    except Exception as e:
        logger.error(f"构建请求头失败: {str(e)}")
        return None

def transcribe_audio_xfyun(audio_base64):
    """调用讯飞API进行语音转写"""
    try:
        # 讯飞语音识别API地址
        url = "http://api.xfyun.cn/v1/service/v1/iat"
        
        # 构建请求头
        headers = build_xfyun_request_header(XFYUN_API_KEY, XFYUN_API_SECRET)
        if not headers:
            return None, "构建请求头失败"
        
        # 构建请求体
        data = {
            'audio': audio_base64,
            'format': 'audio/L16;rate=16000',
            'engine_type': 'sms16k',
            'aue': 'raw',
            'language': 'zh_cn',
            'accent': 'mandarin',
            'result_type': 'plain',
            'voice_name': 'xiaoyan'
        }
        
        logger.info("正在调用讯飞API进行语音转写...")
        
        # 发送请求
        response = requests.post(url, headers=headers, data=data, timeout=30)
        
        if response.status_code == 200:
            result = response.json()
            logger.info(f"讯飞API响应: {result}")
            
            if result.get('code') == '0':
                # 提取转写结果
                transcript = result.get('data', '')
                return transcript, None
            else:
                error_msg = result.get('desc', '转写失败')
                return None, f"讯飞API错误: {error_msg}"
        else:
            return None, f"HTTP错误: {response.status_code}"
            
    except requests.exceptions.Timeout:
        return None, "请求超时，请检查网络连接"
    except requests.exceptions.RequestException as e:
        logger.error(f"请求异常: {str(e)}")
        return None, f"网络请求失败: {str(e)}"
    except Exception as e:
        logger.error(f"转写过程异常: {str(e)}")
        return None, f"转写过程异常: {str(e)}"

@app.route('/api/transcribe', methods=['POST'])
def transcribe_audio():
    """处理音频转写请求"""
    try:
        # 检查是否有文件上传
        if 'audio' not in request.files:
            return jsonify({'success': False, 'error': '没有上传音频文件'}), 400
        
        file = request.files['audio']
        
        # 检查文件是否为空
        if file.filename == '':
            return jsonify({'success': False, 'error': '没有选择文件'}), 400
        
        # 检查文件类型
        if not allowed_file(file.filename):
            return jsonify({'success': False, 'error': '不支持的音频格式'}), 400
        
        # 保存上传的文件
        filename = secure_filename(file.filename)
        timestamp = str(int(time.time()))
        filename = f"{timestamp}_{filename}"
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        
        logger.info(f"保存上传文件: {file_path}")
        file.save(file_path)
        
        # 将音频文件转换为base64
        audio_base64 = get_audio_file_base64(file_path)
        if not audio_base64:
            return jsonify({'success': False, 'error': '音频文件处理失败'}), 500
        
        # 调用讯飞API进行转写
        transcript, error = transcribe_audio_xfyun(audio_base64)
        
        # 删除临时文件
        try:
            os.remove(file_path)
        except:
            pass
        
        if error:
            return jsonify({'success': False, 'error': error}), 500
        
        if transcript:
            return jsonify({'success': True, 'transcript': transcript})
        else:
            return jsonify({'success': False, 'error': '转写结果为空'}), 500
            
    except Exception as e:
        logger.error(f"转写请求处理失败: {str(e)}")
        return jsonify({'success': False, 'error': f'服务器内部错误: {str(e)}'}), 500

@app.route('/api/health', methods=['GET'])
def health_check():
    """健康检查接口"""
    return jsonify({'status': 'healthy', 'service': 'audio-transcription'})

@app.errorhandler(413)
def too_large(e):
    """文件过大错误处理"""
    return jsonify({'success': False, 'error': '文件大小超过限制（最大50MB）'}), 413

@app.errorhandler(500)
def server_error(e):
    """服务器错误处理"""
    return jsonify({'success': False, 'error': '服务器内部错误'}), 500

if __name__ == '__main__':
    # 检查必要的环境变量
    if XFYUN_APPID == "your_appid_here" or XFYUN_API_KEY == "your_api_key_here":
        logger.warning("警告: 讯飞API配置未设置，请在代码中配置正确的APPID和API_KEY")
        print("请先在 app.py 文件中配置正确的讯飞开放平台凭证:")
        print("- XFYUN_APPID: 你的应用ID")
        print("- XFYUN_API_KEY: 你的API密钥")
        print("- XFYUN_API_SECRET: 你的API密钥")
        print("\n获取方式: https://www.xfyun.cn/")
    
    logger.info("启动讯飞语音转写服务...")
    logger.info("服务地址: http://localhost:5000")
    logger.info("前端页面: http://localhost:5000/index.html")
    
    app.run(host='0.0.0.0', port=5000, debug=True)
